#include "options.h"

/*** Options
 * constructor
 * ***/
#undef __FUNCT__
#define __FUNCT__ "Options"
Options::Options()
: Nx(128), Ny(128), adaptive(true), lambda(0.5), T(1.8), num_snapshot(MAX_SNAPSHOTS), take_snapshot(PETSC_FALSE)
{
  domain[0][0] = 0.;
  domain[0][1] = 1.;
  domain[1][0] = 0.;
  domain[1][1] = 1.;
}

/*** ~Options
* destructor
* ***/
#undef __FUNCT__
#define __FUNCT__ "~Options"
Options::~Options()
{
  
}

/*** read_options
 * read options from command line
 * ***/
#undef __FUNCT__
#define __FUNCT__ "read_options"
void Options::read_options()
{
  // Temporary data for option setting
  PetscBool             flag;
  integer               mesh_max = 2, mesh_max_ = mesh_max;
  integer               mesh_array[2];
  integer               domain_max = 4, domain_max_ = domain_max;
  real                  domain_array[4];
  
  // Print HELP
  PetscOptionsHasName(PETSC_NULL, "--help", &flag);
  if( flag ) {
    PetscPrintf(PETSC_COMM_WORLD, "Usage:                       ./main [options] or mpitun -np #proc ./main [options]\n");
    PetscPrintf(PETSC_COMM_WORLD, "Suggested options:           -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps\n");
    PetscPrintf(PETSC_COMM_WORLD, "Configuration options:\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -lambda f                  set CFL number to f\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -mesh d,d                  set mesh sizes in x-dir and y-dir\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -adaptive                  set adaptive time step\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -final-time f              set final time\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -domain f,f,f,f            set domain boundaries to [f,f]x[f,f]\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -snapshot f,f,f,f,...      save snapshots of solutions at various times [f] (check for ordering and time limits)\n");
    PetscPrintf(PETSC_COMM_WORLD, "                             cannot take more than %d snapshots (edit tools.h)\n", MAX_SNAPSHOTS);
    PetscPrintf(PETSC_COMM_WORLD, "  -name s                    set name (prefix) for the experminent\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -model s                   choose between 'shear_layer', 'disc_shear_layer', 'steady', 'vortex_box' and 'random_interface'\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -refinements d             number of refinements of the grid\n");
    PetscPrintf(PETSC_COMM_WORLD, "  -simulations s             number of simulation for each grid\n");
    
    return;
  }
  // Get lambda option (CFL)
  PetscOptionsGetReal(PETSC_NULL, "-lambda", &lambda, &flag);
  if( !flag ) PetscPrintf(PETSC_COMM_WORLD, "[INFO] \"-lambda\" option not found, falling back to default, lambda = %f\n", lambda);
  // Get mesh sizes
  PetscOptionsGetIntArray(PETSC_NULL, "-mesh", mesh_array, &mesh_max_, &flag);
  if( !flag ) {
    PetscPrintf(PETSC_COMM_WORLD, "[INFO] \"-mesh\" option not found, falling back to default, mesh = %d x %d\n", Nx, Ny);
  } else if( mesh_max_ != mesh_max ) {
    PetscPrintf(PETSC_COMM_WORLD, "[WARNING] invalid \"-mesh\" option (must be of the form -mesh Nx,Ny), falling back to default, mesh = %d x %d\n", Nx, Ny);
  } else {
    Nx = mesh_array[0];
    Ny = mesh_array[1];
  }
  // Get final time options
  PetscOptionsGetReal(PETSC_NULL, "-final-time", &T, &flag);
  if( !flag ) PetscPrintf(PETSC_COMM_WORLD, "[INFO] \"-final-time\" option not found, falling back to default, T = %f\n", T);
  // Get adaptive option
  PetscOptionsHasName(PETSC_NULL, "-adaptive", &flag);
  if( !flag ) {
    adaptive = false;
    PetscPrintf(PETSC_COMM_WORLD, "[WARNING] \"-adaptive\" is not set!");
  }
  // Get domain info
  PetscOptionsGetRealArray(PETSC_NULL, "-domain", domain_array, &domain_max_, &flag);
  if( !flag ) {
    PetscPrintf(PETSC_COMM_WORLD, "[INFO] \"-domain\" option not found, falling back to default, domain = {{%f, %f}, {%f, %f}}\n",
                domain[0][0], domain[0][1], domain[1][0], domain[1][1]);
  } else if( mesh_max_ != mesh_max ) {
    PetscPrintf(PETSC_COMM_WORLD, "[WARNING] invalid \"-domain\" option (must be of the form -mesh L,R,B,T), falling back to default, domain = {{%f, %f}, {%f, %f}}\n",
                domain[0][0], domain[0][1], domain[1][0], domain[1][1]);
  } else {
    domain[0][0] = domain_array[0];
    domain[0][1] = domain_array[1];
    domain[1][0] = domain_array[2];
    domain[1][1] = domain_array[3];
  }
  // Setup snapshot information
  PetscOptionsGetRealArray(PETSC_NULL, "-snapshots", times_snapshot, &num_snapshot, &take_snapshot);
  // Setup name
  PetscOptionsGetString(PETSC_NULL, "-name", name, PETSC_MAX_PATH_LEN, &flag);
  time_t        timer;
  time(&timer);
  if( !flag ) sprintf(name, "unnamed_%ld", timer);
  PetscOptionsGetString(PETSC_NULL, "-model", model, PETSC_MAX_PATH_LEN, &flag);
}
